﻿/* Muaz Khan – http://dashingquill.web.officelive.com */
using System;
using System.Linq;
using DTweet.Models;
using System.Collections.Generic;

namespace DTweet.Helpers
{
    public static class TweetsExtensions
    {
        /***********************************
         * helper for adding new tweet message
         ***********************************/
        public static Tweet AddTweet(this DatabaseEntities db, string message, string circles, string users)
        {
            var usersToShare = "";
            if (users != "NoUser") usersToShare = users.Substring(0, users.Length - 1);

            if (circles == "Public") usersToShare = "AllUsers";
            else
            {
                /* Splitting circle tokens and getting members from splitted circles */
                foreach (var s in circles.Split(','))
                {
                    var circle = db.Circles.Where(c => c.Token == s).FirstOrDefault();
                    if (circle != null && circle.MembersCount > 0)
                    {
                        usersToShare += circle.Members + ",";
                    }
                }
                if (usersToShare.EndsWith(",")) usersToShare = usersToShare.Substring(0, usersToShare.Length - 1);
            }

            var tweet = new Tweet
            {
                Message = message,
                TweetingTime = DateTime.Now,
                UserToken = Static.CurrentUser.UniqueToken,
                IsPublic = true,
                TweetToken = TrackTweetToken(db)
            };

            if (usersToShare != "AllUsers") tweet.SharedTo = usersToShare;
            else tweet.SharedTo = "Public";

            try
            {
                db.Tweets.AddObject(tweet);
                db.SaveChanges();
            }
            catch (Exception ex)
            {
                ex.Message.AlertForError(); /* Exposing the original error message; Security, Security, Security: Yes Sir! */
            }
            return tweet;
        }

        /***********************************
         * Validate if tweet-token already taken
         ***********************************/
        static string TrackTweetToken(DatabaseEntities db)
        {
        Back:

            var randomNumber = RandomNumbers.GetRandomNumbers();
            var tweet = db.Tweets.Where(a => a.TweetToken == randomNumber).FirstOrDefault();
            if (tweet != null) goto Back;

            return randomNumber;
        }

        /***********************************
         * Get tweet by tweet-token and user-token
         ***********************************/
        public static Tweet GetTweet(this string tweetToken, string userToken, DatabaseEntities db)
        {
            return db.Tweets.Where(t => t.TweetToken == tweetToken && t.UserToken == userToken).FirstOrDefault();
        }

        /***********************************
         * Getting tweets for user's homepage!
         ***********************************/
        public static List<Tweet> GetTweetsForUserPage(this DatabaseEntities db, string userToken)
        {
            var currentUser = Static.CurrentUser;
            var circles = db.Circles.Where(c => c.UserToken == currentUser.UniqueToken); /* Circles of the User; whose page is currently opened */
            var tweets = db.Tweets.Where(t => t.UserToken == userToken).ToList(); /* Tweets shared by this user; whose page is opened */

            /* Not logged-in, displaying only public tweets */
            if (currentUser == null) tweets = tweets.Where(t => t.SharedTo == "Public").ToList();

            /* Logged in, also the owner of the tweet */
            if (currentUser != null && currentUser.UniqueToken == userToken)
            {
                foreach (var c in circles)
                {
                    if (c.MembersCount > 0) /* That user created any circle! */
                    {
                        /* Tracking all users he is following, also checking whether those tracked-users' tweets are public or shared with this user */
                        foreach (var ct in c.Members.Split(',').Select(m => db.Tweets.Where(t => t.UserToken == m.Trim() && (t.SharedTo == "Public" || t.SharedTo.Contains(currentUser.UniqueToken)))))
                        {
                            tweets.AddRange(ct);
                        }
                    }
                }
            }

            /* Logged in, but not the owner of the tweet */
            if (currentUser != null && currentUser.UniqueToken != userToken)
            {
                tweets = tweets.Where(t => t.SharedTo == "Public" || t.SharedTo.Contains(currentUser.UniqueToken)).ToList();
            }

            tweets = tweets.Distinct().OrderByDescending(t => t.Id).Take(20).ToList(); /* Recent 20 tweets */

            return tweets;
        }

        /***********************************
         * Status of a single post
         ***********************************/
        public static void Status(this DatabaseEntities db, string tweetToken, string postTitle)
        {
            ErrorsHelper.IsError = false;
            ResultHelper.Tweet = null;
            ResultHelper.User = null;

            try
            {
                var tweet = db.Tweets.Where(t => t.TweetToken == tweetToken).FirstOrDefault();

                if (tweet == null || tweet.Message.FetchPostUrl() != postTitle) throw new Exception("goto homepage");

                var currentUser = Static.CurrentUser;
                if (tweet.SharedTo != "Public" && currentUser == null) throw new Exception("goto homepage");

                if (currentUser != null && tweet.SharedTo != "Public")
                {
                    var currentUserToken = Static.CurrentUser.UniqueToken;
                    if (!tweet.SharedTo.Contains(currentUserToken))
                    {
                        if (tweet.UserToken != currentUserToken) throw new Exception("goto homepage");
                    }
                }

                var user = db.Accounts.Where(a => a.UniqueToken == tweet.UserToken).FirstOrDefault();

                ResultHelper.Tweet = tweet;
                ResultHelper.User = user;
            }
            catch (Exception ex)
            {
                ex.Message.AlertForError();
            }
        }

        /***********************************
         * Saving edited-post's changes
         ***********************************/
        public static void SubmitChanges(this DatabaseEntities db, string id, string tweetMessage)
        {
            ErrorsHelper.IsError = false;
            ResultHelper.TweetMessage = null;
            try
            {
                var tweet = db.Tweets.Where(t => t.TweetToken == id && t.UserToken == Static.CurrentUser.UniqueToken).FirstOrDefault();
                if (tweet == null) throw new Exception("Post not found or you are not the owner!");

                tweet.Message = tweetMessage.Validate();
                tweet.EditingTime = DateTime.Now;

                if (tweet.EditCount == 0) tweet.EditCount = 1;
                else tweet.EditCount++;

                db.SaveChanges();
                ResultHelper.TweetMessage = tweet.Message.ReplaceAll();
            }
            catch (Exception ex)
            {
                ex.Message.AlertForError();
            }
        }
    }
}